import java.lang.reflect.Constructor;

public class TestNewInstance {
    public static void main(String[] args) {
        /**
         * 使用 newInstance 时必须保证： 1.这个类已经加载, 2. 这个类已经连接；
         * newInstance 实际上把 new 操作分解成了两步： 先调用class 加载某个类, 再进行实例化;
         */

        Test2 t2 = new Test2();
        t2.t();


        try {
            Constructor constructor = Class.forName(Test3.class.getName()).getConstructor();
            constructor.newInstance();

        } catch (Exception e) {
            System.out.println(">> Constructor 调用私有构造失败");
            System.out.println(e.getMessage());
        }

        try {
            Test3 t3 = (Test3) Class.forName(Test3.class.getName()).newInstance();
            t3.t();
        } catch (Exception e) {
            System.out.println(">> newInstance 调用私有构造失败");
        }

        /**
         * newInstance()区别
         *
         * Class.newInstance()只能反射无参的构造器；
         * Constructor.newInstance()可以反任何构造器；
         *
         * Class.newInstance()需要构造器可见(visible)；
         * Constructor.newInstance()可以反私有构造器；
         *
         * Class.newInstance()对于捕获或者未捕获的异常均由构造器抛出;
         * Constructor.newInstance()通常会把抛出的异常封装成InvocationTargetException抛出；
         *
         *
         */

    }
}

class Test2{

    public void t() {
        System.out.println("new");
    }
}
class Test3{
    private Test3() {
        System.out.println("调用私有构造函数成功");
    }
    public void t() {
        System.out.println("newInstance");
    }
}
